var express = require('express')
var router = express.Router()
const db = require('../db/index')
// 用来加密密码
const bcrypt = require('bcryptjs')

// 用这个包来生成 Token 字符串
const jwt = require('jsonwebtoken')
// 导入配置文件
const config = require('../config')

// 1. 导入验证表单数据的中间件
const expressJoi = require('@escook/express-joi')
// 2. 导入需要的验证规则对象
const { reg_login_schema } = require('../schema/user')

/* 
// 注册新用户
// 3. 在注册新用户的路由中，声明局部中间件，对当前请求中携带的数据进行验证
// 3.1 数据验证通过后，会把这次请求流转给后面的路由处理函数
// 3.2 数据验证失败后，终止后续代码的执行，并抛出一个全局的 Error 错误，进入全局错误级别中间件中进行处理
 */

// 注册新用户
router.post('/register', expressJoi(reg_login_schema), (req, res) => {
  // 接收表单数据
  const userinfo = req.body
  console.log(userinfo, '+++++++++++++++')
  // 判断数据是否合法
  if (!userinfo.username || !userinfo.password) {
    return res.send({ code: 400, message: '用户名或密码不能为空！' })
  }

  const sql = `select * from user where username=?`
  db.query(sql, [userinfo.username], function (err, results) {
    // 执行 SQL 语句失败
    if (err) {
      return res.send({ code: 200, message: err.message })
    }
    // 用户名被占用
    if (results.length > 0) {
      return res.send({
        code: 400,
        message: '用户名被占用，请更换其他用户名！',
      })
    }
    // TODO: 用户名可用，继续后续流程...
    // 对用户的密码,进行 bcrype 加密，返回值是加密之后的密码字符串
    userinfo.password = bcrypt.hashSync(userinfo.password, 10)

    const sql = 'insert into user set ?'
    db.query(
      sql,
      {
        username: userinfo.username,
        password: userinfo.password,
        phone: userinfo.phone,
      },
      function (err, results) {
        // 执行 SQL 语句失败
        if (err) return res.send({ code: 400, message: err.message })
        // SQL 语句执行成功，但影响行数不为 1
        if (results.affectedRows !== 1) {
          return res.send({ code: 400, message: '注册用户失败，请稍后再试！' })
        }
        // 注册成功
        res.send({ code: 200, message: '注册成功！' })
      }
    )
  })
  // res.send('register OK')
})

// 登录
router.post('/login', expressJoi(reg_login_schema), (req, res) => {
  // 接收表单数据
  const userinfo = req.body
  console.log(userinfo, '=============')
  // 定义sql语句
  const sql = `select * from user where username=?`
  // 执行 SQL 语句，查询用户的数据：
  db.query(sql, userinfo.username, function (err, results) {
    // 执行 SQL 语句失败
    if (err) return res.cc(err)
    // 执行 SQL 语句成功，但是查询到数据条数不等于 1
    if (results.length !== 1) return res.cc('登录失败！')
    // 调用 `bcrypt.compareSync(用户提交的密码, 数据库中的密码)` 方法比较密码是否一致，返回值是布尔值（true 一致、false 不一致）
    // 拿着用户输入的密码,和数据库中存储的密码进行对比
    const compareResult = bcrypt.compareSync(
      userinfo.password,
      results[0].password
    )
    // 如果对比的结果等于 false, 则证明用户输入的密码错误
    if (!compareResult) {
      return res.cc('登录失败！')
    }
    // 登录成功，生成 Token 字符串
    // 剔除完毕之后，user 中只保留了用户的 id, username, nickname, phone 这四个属性的值
    const user = { ...results[0], password: '' }
    // 生成 Token 字符串
    const tokenStr = jwt.sign(user, config.jwtSecretKey, {
      expiresIn: '10h', // token 有效期为 10 个小时
    })
    res.send({
      code: 200,
      message: '登录成功！',
      data: user,
      // 为了方便客户端使用 Token，在服务器端直接拼接上 Bearer 的前缀
      token: 'Bearer ' + tokenStr,
    })
  })
  // res.send('login OK')
})

module.exports = router
